package com.isd.pool.dao;

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

import com.isd.global.dao.BaseDAO;
import com.isd.global.excepciones.PreexistingEntityException;
import com.isd.global.excepciones.RollbackFailureException;
import com.isd.pool.modelo.BasesCondicionesAdicionales;
import com.isd.pool.modelo.BasesCondicionesAdicionalesPK;
import com.isd.pool.modelo.CondicionesPagoPool;
import com.isd.pool.modelo.CondicionesPagoPoolPK;
import com.isd.pool.modelo.ItemPicking;
import com.isd.pool.modelo.ItemProductoPool;
import com.isd.pool.modelo.ItemProductoPoolPK;
import com.isd.pool.modelo.Pool;
import com.isd.pool.modelo.ReservasPool;
import com.isd.venta.modelo.Cliente;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.ejb.Stateless;
import javax.persistence.Query;

/**
 *
 * @author Claudio
 */
@Stateless
public class PoolDAO extends BaseDAO{

    public Pool refresh(Pool pool){

        getEntityManager().refresh(pool);
        return pool;
    }

    /**
     *
     * @return Lista de pooles visibles para el usuario
     * Un pool está visible si se encuentra dentro del rango de de tiempo definido
     * independientemente si se vendieron todas las cantidades
     */
    public List<Pool> getVentasPublicasVisibles(){

        try {

            String sQuery = "SELECT p FROM Pool p  WHERE ";
            sQuery += " p.disponibleDesde <= :desde ";
            sQuery += " AND p.disponibleHasta >= :hasta ";
            sQuery += " AND p.tipoAcceso = 'P' ";
            sQuery += " AND  p.debaja = 'N' ";
            sQuery += " AND  (p.estado = 'Activo' or p.estado = 'Cerrado' or p.estado = 'Finalizado con éxito' )";
            //sQuery += " AND  p.cantidadDisponible >= 0 ";
            sQuery += " ORDER BY p.nroPool ";

            Query q = getEntityManager().createQuery(sQuery);

            q.setParameter("desde", new java.util.Date());
            q.setParameter("hasta", new java.util.Date());

            //Por seguridad seteamos en 10
            q.setMaxResults(10);

            return q.getResultList();

        } catch (Exception e) {

            Logger.getLogger(getClass().getName()).log(Level.SEVERE, "getVentasPublicasVisibles", e);
            return new ArrayList<Pool>();
        }
    }

    public List<Pool> getVentasRestringidasVisibles(){

        try {

            String sQuery = "SELECT p FROM Pool p  WHERE ";
            sQuery += " p.disponibleDesde <= :desde ";
            sQuery += " AND p.disponibleHasta >= :hasta ";
            sQuery += " AND p.tipoAcceso = 'R' ";
            sQuery += " AND  p.debaja = 'N' ";
            sQuery += " AND  (p.estado = 'Activo' or p.estado = 'Cerrado' or p.estado = 'Finalizado con éxito' )";
            //sQuery += " AND  p.cantidadDisponible >= 0 ";
            sQuery += " ORDER BY p.nroPool ";

            Query q = getEntityManager().createQuery(sQuery);

            q.setParameter("desde", new java.util.Date());
            q.setParameter("hasta", new java.util.Date());

            //Por seguridad seteamos en 10
            q.setMaxResults(10);

            return q.getResultList();

        } catch (Exception e) {

            Logger.getLogger(getClass().getName()).log(Level.SEVERE, "getVentasRestringidasVisibles", e);
            return new ArrayList<Pool>();
        }
    }

    public List<Pool> getVentasParaCerrar(){

        try {

            String sQuery = "SELECT p FROM Pool p  WHERE ";
            sQuery += " p.disponibleDesde <= :desde ";
            sQuery += " AND p.disponibleHasta <= :hasta ";
            sQuery += " AND  p.debaja = 'N' ";
            sQuery += " AND  p.estado = 'Activo' ";
            sQuery += " AND  p.cantidadDisponible >= 0 ";
            sQuery += " ORDER BY p.nroPool ";

            Query q = getEntityManager().createQuery(sQuery);

            q.setParameter("desde", new java.util.Date());
            q.setParameter("hasta", new java.util.Date());

            //Por seguridad seteamos en 10
            q.setMaxResults(10);

            return q.getResultList();

        } catch (Exception e) {
            Logger.getLogger(getClass().getName()).log(Level.SEVERE, "getVentasParaCerrar", e);
            return new ArrayList<Pool>();
        }
    }

    public Pool getPool(String codigoAcceso) {

        try {

            String sQuery = "SELECT p FROM Pool p  WHERE ";
            sQuery += " p.debaja = 'N' ";
            sQuery += " AND p.codigoAcceso = :codigoAcceso ";
            sQuery += " ORDER BY p.nroPool DESC ";

            Query q = getEntityManager().createQuery(sQuery);            
            q.setParameter("codigoAcceso", codigoAcceso); 
            q.setMaxResults(1);
            
            return (Pool) q.getSingleResult();

        } catch (Exception e) {
            Logger.getLogger(getClass().getName()).log(Level.SEVERE, "getPool", e);
            return null;
        }
    }
    
    public List<Pool> getLista() {

        try {

            String sQuery = "SELECT p FROM Pool p  WHERE ";
            sQuery += " p.debaja = 'N' ";
            sQuery += " ORDER BY p.nroPool DESC ";

            Query q = getEntityManager().createQuery(sQuery);

            q.setMaxResults(10);

            return q.getResultList();

        } catch (Exception e) {

            Logger.getLogger(getClass().getName()).log(Level.SEVERE, "getLista", e);
            return new ArrayList<Pool>();
        }

    }

    public List<ReservasPool> getReservasPorCliente(Cliente cliente, String estado) {
        try {
            String sQuery = "SELECT r FROM ReservasPool r WHERE ";
            sQuery += " r.debaja = 'N' ";
            sQuery += " AND r.nroCuenta = :nroCuenta ";
            sQuery += " AND r.estado = :estado ";
            

            Query q = getEntityManager().createQuery(sQuery);
            q.setParameter("nroCuenta", cliente.getNrocta());
            q.setParameter("estado", estado);

            return q.getResultList();

        } catch (Exception e) {
            Logger.getLogger(getClass().getName()).log(Level.SEVERE, "getReservasPorCliente", e);
            return new ArrayList<ReservasPool>();
        }
    }

    public Integer getNumeroMaximoPool() {

        try {
            String sQuery = "SELECT MAX(p.nroPool) FROM Pool p ";

            Query q = getEntityManager().createQuery(sQuery);
            Integer cant = (Integer) q.getSingleResult();

            if(cant==null){
                cant = Integer.parseInt("0");
            }

            return cant;

        } catch (NumberFormatException e) {
            Logger.getLogger(getClass().getName()).log(Level.SEVERE, "getNumeroMaximoPool", e);
            return Integer.parseInt("0");
        }

    }

    public void eliminarCondicionPago(CondicionesPagoPool item) {
        try {
            CondicionesPagoPoolPK idPK = new CondicionesPagoPoolPK();
            idPK.setNroPool(item.getNroPool());
            idPK.setOrden(item.getOrden());
            eliminar(CondicionesPagoPool.class, idPK);
        } catch (PreexistingEntityException ex) {
            //Logger.getLogger(PoolDAO.class.getName()).log(Level.SEVERE, null, ex);
        } catch (RollbackFailureException ex) {
            //Logger.getLogger(PoolDAO.class.getName()).log(Level.SEVERE, null, ex);
        } catch (Exception ex) {
            //Logger.getLogger(PoolDAO.class.getName()).log(Level.SEVERE, null, ex);
        }

    }

    public void eliminarItemProducto(ItemProductoPool item) {
        try {
            ItemProductoPoolPK idPk = new ItemProductoPoolPK(item.getNroPool(), item.getOrden());
            eliminar(ItemProductoPool.class, idPk);
        } catch (PreexistingEntityException ex) {
            //Logger.getLogger(PoolDAO.class.getName()).log(Level.SEVERE, null, ex);
        } catch (RollbackFailureException ex) {
            //Logger.getLogger(PoolDAO.class.getName()).log(Level.SEVERE, null, ex);
        } catch (Exception ex) {
            //Logger.getLogger(PoolDAO.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    public void eliminarBaseCondicionesAdicionales(BasesCondicionesAdicionales item) {
        try {
            BasesCondicionesAdicionalesPK idPk = new BasesCondicionesAdicionalesPK(item.getNroPool(), item.getNroitm());
            eliminar(BasesCondicionesAdicionales.class, idPk);
        } catch (PreexistingEntityException ex) {
            //Logger.getLogger(PoolDAO.class.getName()).log(Level.SEVERE, null, ex);
        } catch (RollbackFailureException ex) {
            //Logger.getLogger(PoolDAO.class.getName()).log(Level.SEVERE, null, ex);
        } catch (Exception ex) {
            //Logger.getLogger(PoolDAO.class.getName()).log(Level.SEVERE, null, ex);
        }

    }

    public BigDecimal getCantidadReservadaByPool(Integer nroPool,String estado) {
        
        try {
            
            getEntityManager().flush();
                        
            String sQuery = "SELECT SUM(i.cantidad) FROM ItemReserva i ";
            sQuery += " WHERE i.debaja = 'N' ";
            sQuery += " AND i.nroPool = :nroPool ";
            sQuery += " AND i.reserva.estado = :estado";
            
            Query q = getEntityManager().createQuery(sQuery);
            q.setParameter("nroPool", nroPool);
            q.setParameter("estado", estado);
            
            BigDecimal cant = (BigDecimal) q.getSingleResult();

            if(cant==null){
                cant = BigDecimal.ZERO;
            }

            return cant;

        } catch (Exception e) {
            Logger.getLogger(getClass().getName()).log(Level.SEVERE, "getCantidadReservadaByPool", e);
            return BigDecimal.ZERO;
        }
    }

    public BigDecimal getCantidadReservadaByItemProductoPool(Integer nroPool, String estado ,String tippro, String artcod) {
        
        try {
            String sQuery = "SELECT SUM(i.cantidad) FROM ItemReserva i ";
            sQuery += " WHERE i.debaja = 'N' ";
            sQuery += " AND i.nroPool = :nroPool ";
            sQuery += " AND i.reserva.estado = :estado";
            sQuery += " AND i.tippro = :tippro";
            sQuery += " AND i.artcod = :artcod";
            
            Query q = getEntityManager().createQuery(sQuery);
            q.setParameter("nroPool", nroPool);
            q.setParameter("estado", estado);
            q.setParameter("tippro", tippro);
            q.setParameter("artcod", artcod);
            
            BigDecimal cant = (BigDecimal) q.getSingleResult();

            if(cant==null){
                cant = BigDecimal.ZERO;
            }

            return cant;

        } catch (Exception e) {
            Logger.getLogger(getClass().getName()).log(Level.SEVERE, "getCantidadReservadaByItemProductoPool", e);
            return BigDecimal.ZERO;
        }
    }
    
    public int getCantidadPickingByItemProductoPool(int nroPool, String tippro, String artcod) {
        try {
            
            String sQuery = "SELECT SUM(i.cantid) FROM ItemPicking i ";
            sQuery += " WHERE i.debaja = 'N' ";
            sQuery += " AND i.nrpool = :nroPool ";            
            sQuery += " AND i.producto.tippro = :tippro";
            sQuery += " AND i.producto.artcod = :artcod";
            
            Query q = getEntityManager().createQuery(sQuery);
            q.setParameter("nroPool", nroPool);            
            q.setParameter("tippro", tippro);
            q.setParameter("artcod", artcod);
            
            Long cant = ((Long) q.getSingleResult());
            
            return (cant==null? 0 : cant.intValue());

        } catch (Exception e) {
            Logger.getLogger(getClass().getName()).log(Level.SEVERE, "getCantidadPickingByItemProductoPool", e);
            return 0;
        }
    }

    public List<Pool> getPoolByDescripcion(String query) {
        
         try {

            String sQuery = "SELECT p FROM Pool p  WHERE ";
            sQuery += " p.debaja = 'N' ";
            sQuery += " AND p.descripcion LIKE :sQuery ";
            sQuery += " ORDER BY p.nroPool DESC ";

            Query q = getEntityManager().createQuery(sQuery);
            
            q.setParameter("sQuery", "%"+query+"%");
            q.setMaxResults(10);

            return q.getResultList();

        } catch (Exception e) {

            Logger.getLogger(getClass().getName()).log(Level.SEVERE, "getPoolByDescripcion", e);
            return new ArrayList<Pool>();
        }

    }

    
}
